use serde::{Deserialize, Serialize};
use serde_repr::Serialize_repr;

#[derive(Clone, Debug, Deserialize)]
pub struct NearByPoiRes {
    pub data: NearByPoiData,
}
#[derive(Clone, Debug, Deserialize)]
pub struct NearByPoiData {
    pub audit_id: u32,
    pub poi_id: u32,
    pub related_credential: String,
}

#[derive(Clone, Debug, Serialize)]
pub struct NearByPoi {
    kf_info: String,
    pic_list: String,
    service_infos: String,
    store_name: String,
    contract_phone: String,
    hour: String,
    company_name: String,
    credential: String,
    address: String,
    qualification_list: String,
    is_comm_nearby: String,
    poi_id: String,
    map_poi_id: String,
}

impl NearByPoi {
    pub fn builder() -> NearByPoiBuilder {
        NearByPoiBuilder {
            is_comm_nearby: Some("1".to_owned()),
            poi_id: Some(String::default()),
            map_poi_id: Some(String::default()),
            ..Default::default()
        }
    }
}

#[derive(Clone, Debug, Serialize, Default)]
pub struct NearByPoiBuilder {
    kf_info: Option<String>,
    pic_list: Option<String>,
    service_infos: Option<String>,
    store_name: Option<String>,
    contract_phone: Option<String>,
    hour: Option<String>,
    company_name: Option<String>,
    credential: Option<String>,
    address: Option<String>,
    qualification_list: Option<String>,
    is_comm_nearby: Option<String>,
    poi_id: Option<String>,
    map_poi_id: Option<String>,
}
impl NearByPoiBuilder {
    pub fn kf_info<T: AsRef<str>>(mut self, info: T) -> NearByPoiBuilder {
        self.kf_info = Some(info.as_ref().to_owned());
        self
    }
    pub fn pic_list<T>(mut self, list: T) -> Self
    where
        T: AsRef<str>,
    {
        self.pic_list = Some(list.as_ref().to_owned());
        self
    }

    pub fn service_infos<T>(mut self, infos: T) -> Self
    where
        T: AsRef<str>,
    {
        self.service_infos = Some(infos.as_ref().to_owned());
        self
    }

    pub fn store_name<T>(mut self, name: T) -> Self
    where
        T: AsRef<str>,
    {
        self.store_name = Some(name.as_ref().to_owned());
        self
    }

    pub fn comtract_phone<T>(mut self, phone: T) -> Self
    where
        T: AsRef<str>,
    {
        self.contract_phone = Some(phone.as_ref().to_owned());
        self
    }

    pub fn hour<T>(mut self, hour: T) -> Self
    where
        T: AsRef<str>,
    {
        self.hour = Some(hour.as_ref().to_owned());
        self
    }

    pub fn company_name<T>(mut self, name: T) -> Self
    where
        T: AsRef<str>,
    {
        self.company_name = Some(name.as_ref().to_owned());
        self
    }

    pub fn credential<T>(mut self, credential: T) -> Self
    where
        T: AsRef<str>,
    {
        self.credential = Some(credential.as_ref().to_owned());
        self
    }

    pub fn address<T>(mut self, address: T) -> Self
    where
        T: AsRef<str>,
    {
        self.address = Some(address.as_ref().to_owned());
        self
    }

    pub fn qualification_list<T>(mut self, list: T) -> Self
    where
        T: AsRef<str>,
    {
        self.qualification_list = Some(list.as_ref().to_owned());
        self
    }

    pub fn poi_id<T>(mut self, id: T) -> Self
    where
        T: AsRef<str>,
    {
        self.poi_id = Some(id.as_ref().to_owned());
        self
    }

    pub fn map_poi_id<T>(mut self, id: T) -> Self
    where
        T: AsRef<str>,
    {
        self.map_poi_id = Some(id.as_ref().to_owned());
        self
    }

    pub fn build(self) -> NearByPoi {
        let need = "必填";
        NearByPoi {
            kf_info: self.kf_info.expect(need),
            pic_list: self.pic_list.expect(need),
            service_infos: self.service_infos.expect(need),
            store_name: self.store_name.expect(need),
            contract_phone: self.contract_phone.expect(need),
            hour: self.hour.expect(need),
            company_name: self.company_name.expect(need),
            credential: self.credential.expect(need),
            address: self.address.expect(need),
            qualification_list: self.qualification_list.expect(need),
            is_comm_nearby: self.is_comm_nearby.expect(need),
            poi_id: self.poi_id.unwrap(),
            map_poi_id: self.map_poi_id.unwrap(),
        }
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct DelNearbyPoiReq {
    poi_id: String,
}

impl DelNearbyPoiReq {
    pub fn new<T>(id: T) -> Self
    where
        T: AsRef<str>,
    {
        Self {
            poi_id: id.as_ref().to_owned(),
        }
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct DelNearbyPoiRes;

#[derive(Clone, Debug, Serialize)]
pub struct QueryNearby {
    page: u32,
    page_rows: u32,
}

impl QueryNearby {
    pub fn new(page: u32, rows: u32) -> Self {
        Self {
            page,
            page_rows: rows,
        }
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct QueryNearbyRes {
    pub data: Data,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Data {
    pub max_apply_num: u32,
    pub left_apply_num: u32,
    // TODO: 参数化 data，参考 (data.data的结构)[https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/nearby-poi/getNearbyPoiList.html#data-data-%E7%9A%84%E7%BB%93%E6%9E%84]
    pub data: String,
}

#[derive(Clone, Debug, Serialize)]
pub struct NearbyStatusReq {
    poi_id: String,
    status: NearbyStatus,
}

#[derive(Clone, Debug, Serialize_repr)]
#[repr(u8)]
pub enum NearbyStatus {
    Hidden = 0,
    Show = 1,
}

impl NearbyStatusReq {
    pub fn new<T>(id: T, status: NearbyStatus) -> Self
    where
        T: AsRef<str>,
    {
        Self {
            poi_id: id.as_ref().to_owned(),
            status,
        }
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct NearbyStatusRes;
